package cn.powertime.evaluation.facade.impl;

import cn.powertime.evaluation.Constants;
import cn.powertime.evaluation.DateTransformHourUtil;
import cn.powertime.evaluation.annotation.Facade;
import cn.powertime.evaluation.entity.*;
import cn.powertime.evaluation.facade.DbqPostingsFacade;
import cn.powertime.evaluation.service.*;
import cn.powertime.evaluation.shiro.ShiroUtils;
import cn.powertime.evaluation.vo.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.ListIterator;
import java.util.stream.Collectors;

@Facade
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public class DbqPostingsFacadeImpl implements DbqPostingsFacade {

    @Autowired
    private DbqPostingsService dbqPostingsService;

    @Autowired
    private DbqPostingsLabelService dbqPostingsLabelService;

    @Autowired
    private SysDictService sysDictService;

    @Autowired
    private DbqPostingsUserEventService dbqPostingsUserEventService;

    @Autowired
    private DbqPostingsCommentService dbqPostingsCommentService;

    @Override
    public boolean add(ReqPostingsAddVo addVo) {

        Long id = IdWorker.getId();

        //需要新增的标签
        List<ReqPostingsLabelVo> addCollect = addVo.getLabelList().stream()
                .filter(item -> (item.getId().equals(0L) || item.getId() == null) && StringUtils.isNotBlank(item.getName()))
                .collect(Collectors.toList());

        List<Long> labelList = addVo.getLabelList().stream()
                .filter(item -> !item.getId().equals(0L) && item.getId() != null)
                .collect(Collectors.toList())
                .stream().map(ReqPostingsLabelVo::getId)
                .collect(Collectors.toList());

        //封装需要新增的标签信息
        List<SysDict> addDictList = Lists.newArrayList();
        addCollect.forEach(item->{
            SysDict dict = new SysDict();
            dict.setId(IdWorker.getId());
            dict.setStatus(Constants.STATUS_NORMAL);
            dict.setName(item.getName());
            dict.setCreateTime(LocalDateTime.now());
            dict.setUpdateTime(LocalDateTime.now());
            dict.setTypeId(1130721577013395457L);

            labelList.add(dict.getId());
            addDictList.add(dict);
        });
        //封装帖子和标签的映射关系
        List<DbqPostingsLabel> postingsLabelList = Lists.newArrayList();
        labelList.forEach(item->{
            DbqPostingsLabel dbqPostingsLabel = new DbqPostingsLabel();
            dbqPostingsLabel.setId(IdWorker.getId());
            dbqPostingsLabel.setPostingsId(id);
            dbqPostingsLabel.setLabelValue(item);
            dbqPostingsLabel.setStatus(Constants.STATUS_NORMAL);
            dbqPostingsLabel.setCreateTime(LocalDateTime.now());
            dbqPostingsLabel.setUpdateTime(LocalDateTime.now());
            postingsLabelList.add(dbqPostingsLabel);
        });
        //封装帖子对象
        DbqPostings dbqPostings = new DbqPostings();
        dbqPostings.setId(id);
        dbqPostings.setAudit(1);
        dbqPostings.setContent(addVo.getContent());
        dbqPostings.setTitle(addVo.getTitle());
        dbqPostings.setCreateTime(LocalDateTime.now());
        dbqPostings.setUpdateTime(LocalDateTime.now());
        dbqPostings.setTypeId(addVo.getTypeId());
        dbqPostings.setUserId(ShiroUtils.getUserInfo().getId());
        dbqPostingsService.save(dbqPostings);
        dbqPostingsLabelService.saveBatch(postingsLabelList);
        return sysDictService.saveBatch(addDictList);
    }

    @Override
    public List<RespLableListVo> lableList() {
        return sysDictService.lableList();
    }

    @Override
    public IPage<WebRespPostingsListVo> postingsList(ParamPageVo<WebReqPostingsSearchVo> vo) {
        Page<DbqPostings> page = new Page<>(vo.getPage().getCurrent(), vo.getPage().getSize());
        IPage<WebRespPostingsListVo> indexList = dbqPostingsService.postingsList(page,vo.getParams());
        indexList.getRecords().forEach(item-> {
            item.setRelease(DateTransformHourUtil.transform(item.getCreateDate()));
            Document document = Jsoup.parse(item.getContent());  //  将字符串解析成Document对象
            Elements elements = document.select("img");
            List<String> imgs = Lists.newArrayList();
            ListIterator<Element> listIterator = elements.listIterator();
            while (listIterator.hasNext()){
                imgs.add(listIterator.next().toString());
            }
            item.setImgs(imgs);
        });
        return indexList;
    }

    @Override
    public boolean event(WebReqPostingsEventVo vo) {

        Long uid = ShiroUtils.getUserInfo().getId();
        //增加浏览信息
        if(vo.getEventType() == 3){
            int c = dbqPostingsUserEventService.count(buildWrapper(vo,uid));
            if(c == 0){
                return dbqPostingsUserEventService.save(build(vo,uid));
            }
            return true;
        }
        //建立关系
        if(vo.getType() == 1){
            int c = dbqPostingsUserEventService.count(buildWrapper(vo,uid));
            if(c == 0) {
                return dbqPostingsUserEventService.save(build(vo, uid));
            }
            return true;
        }else{
            //取消关系
            return dbqPostingsUserEventService.remove(buildWrapper(vo,uid));
        }
    }

    @Override
    public boolean comment(WebReqPostingsCommentVo vo) {
        DbqPostingsComment comment = new DbqPostingsComment();
        comment.setId(IdWorker.getId());
        comment.setPid(0L);
        comment.setPostingsId(vo.getId());
        comment.setContent(vo.getContent());
        comment.setAudit(1);
        comment.setUserId(ShiroUtils.getUserInfo().getId());
        comment.setStatus(Constants.STATUS_NORMAL);
        comment.setCreateTime(LocalDateTime.now());
        comment.setUpdateTime(LocalDateTime.now());
        return dbqPostingsCommentService.save(comment);
    }

    @Override
    public IPage<WebRespPostingsCommentListVo> commentList(ParamPageVo<WebReqPostingsCommentSearchVo> vo) {
        Page<DbqPostingsComment> page = new Page<>(vo.getPage().getCurrent(), vo.getPage().getSize());
        IPage<WebRespPostingsCommentListVo> list = dbqPostingsCommentService.commentList(page,vo.getParams());
        list.getRecords().forEach(item-> item.setDate(DateTransformHourUtil.transform(item.getCreateDate())));
        return list;
    }

    @Override
    public WebRespPostingsEventVo postingsEvent(WebReqPostingsSearchEventVo vo) {
        return dbqPostingsUserEventService.postingsEvent(vo,ShiroUtils.getUserInfo().getId());
    }

    private QueryWrapper<DbqPostingsUserEvent> buildWrapper(WebReqPostingsEventVo vo,Long uid){
        QueryWrapper<DbqPostingsUserEvent> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",uid);
        queryWrapper.eq("type",vo.getEventType());
        queryWrapper.eq("status",Constants.STATUS_NORMAL);
        queryWrapper.eq("target_id",vo.getId());
        return queryWrapper;
    }

    private DbqPostingsUserEvent build(WebReqPostingsEventVo vo,Long uid){
        DbqPostingsUserEvent event = new DbqPostingsUserEvent();
        event.setId(IdWorker.getId());
        event.setStatus(Constants.STATUS_NORMAL);
        event.setCreateTime(LocalDateTime.now());
        event.setTargetId(vo.getId());
        event.setType(vo.getEventType());
        event.setUserId(uid);
        event.setUpdateTime(LocalDateTime.now());
        return event;
    }

}
